import threading
import os
import gobject
import gtk
import gtk.glade
from BuildWizException import BuildWizException
from ConfigWindow import ConfigWindow
from DlgNewPlatform import DlgNewPlatform

class MainWindow( threading.Thread):
    def __init__( self, wizard):
        threading.Thread.__init__( self)
        self.__wiz = wizard
        self.__wiz.setMainWindow( self)
        self.__configWin = None
        self.__glade = self.__wiz.getPreferences().getGUIFile( "mainwindow")
        if not os.path.isfile( self.__glade):
            raise BuildWizException( "MainWindow: libglade could not open - [%s]" % self.__glade)
        self.platforms = self.__wiz.getPlatforms()
        self.__xml = gtk.glade.XML( self.__glade)
        if self.__xml:
            self.__makeModel()
            self.__win = self.__xml.get_widget( "MainWindow")
            # We could register any number, or use a
            # special class that automatically
            # registers all callbacks. If you wanted to pass
            # an argument, you would use a tuple like this:
            # dic = { "on button1_clicked" : \
            #                (self.button1_clicked, arg1,arg2) , ...
            #
            self.__win.connect( "destroy", self.close)
            self.__handlers = { "on_quit_activate": self.onQuit
                            , "on_btnConfig_clicked": self.showConfig
                            , "on_btnBuild_clicked": self.onBtnBuild
                            , "on_btnStop_clicked": self.onBtnStop
                            , "on_output_activate": self.__showOutput
                            , "on_config_activate": self.showConfig
                            , "on_generate_pendrive_activate": self.generatePendrive
                            , "onAbout": self.__onAbout
                            , "onNewPlatform": self.__onNewPlatform
                            , "onDeletePlatform": self.__onDeletePlatform
                            , "on_platforms_button_press_event": self.__onButtonPressEvent
                            }
            self.__xml.signal_autoconnect( self.__handlers)
            if self.__makeView():
                self.show()

            self.__btnStop = self.__xml.get_widget( "btnStop")
            self.__btnStop.set_sensitive( False)
            self.__btnConfig = self.__xml.get_widget( "btnConfig")

    def run( self):
        gtk.gdk.threads_init()
        gtk.main()

    def close( self, *kw):
        gtk.main_quit()
        self.__wiz.shutdown()
        return

    def __makeModel( self):
        self.__treeStore = gtk.TreeStore( gobject.TYPE_STRING
                                      , gobject.TYPE_BOOLEAN)
        for item in self.platforms.values():
            self.addPlatform( item)
        return

    def show( self):
        self.__win.show_all()

    def addPlatform( self, platform):
        name = platform.getID()
        self.__treeStore.append( None, (name, None))

    def __makeView( self):
        self.__win.treeview = self.__xml.get_widget( "platforms")
        if self.__win.treeview:
            self.__win.treeview.set_model( self.__treeStore) 

            # 'Platform' column
            self.__rendererPlatform = gtk.CellRendererText()
            self.__columnPlatf = gtk.TreeViewColumn( "PLATFORM"
                                                 , self.__rendererPlatform
                                                 , text=0)

            # The toggle cellrenderer is setup and we allow it to be 
            # changed (toggled) by the user.
            self.__rendererBuild = gtk.CellRendererToggle()
            self.__rendererBuild.set_property( 'activatable', True)
            self.__rendererBuild.connect( 'toggled', self.__buildCbHasBeenToggled, self.__treeStore)

            # 'Build' column
            self.__buildColumn = gtk.TreeViewColumn( "BUILD", self.__rendererBuild)
            self.__buildColumn.add_attribute( self.__rendererBuild, "active", 1)

            self.__win.treeview.append_column( self.__columnPlatf)
            self.__win.treeview.append_column( self.__buildColumn)

            self.__win.treeview.set_search_column( 0)
            self.__columnPlatf.set_sort_column_id( 0)
            return True
        else:
            return False

    def __buildCbHasBeenToggled( self, cell, path, model):
        """
        Sets the toggled state on the toggle button to true or false.
        """
        model[ path][ 1] = not model[ path][ 1]
        self.platforms[ model[ path][ 0]].setBuild( model[ path][ 1])
        #print "Toggle '%s' to: %s" % (model[path][0], model[path][1],)
        return

    def onQuit( self, widget):
        self.close()
        return True

    def __showOutput( self, widget):
        for ow in self.__wiz.outputWins.values():
            ow.show()

    def enableConfigButton( self):
        self.__btnConfig.set_sensitive( True)

    def showConfig( self, widget):
        self.__btnConfig.set_sensitive( False)
        self.__configWin = ConfigWindow( 
                self.__wiz.getPreferences().getGUIFile( "configwindow")
                , self.__wiz, self)
        self.__configWin.show()


    def onBtnBuild( self, button):
        try:
            toBuild = self.__wiz.getPlatformsToBuild()
            if len( toBuild) > 0:
                button.set_sensitive( False)
                self.__wiz.runCMake()
                button.set_sensitive( True)
                self.__btnStop.set_sensitive( True)
                self.__win.iconify()
            else:
                dlg = gtk.MessageDialog( None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, 
                        "Ooooooooooops\n\nVerify if:\n\t1) there is at least one platform selected for build process\n\t2) selected platform are running (Menu > View > Outputs)")
                dlg.run()
                dlg.destroy()
        except BuildWizException, e:
            print "ERROR MainWindow.onBtnBuild(): %s", e

    def onBtnStop( self, widget):
        #platfInBuildProcess = self.__wiz.getPlatformsBuildInProgress()
        #if len( platfInBuildProcess) > 1:
        #    print platfInBuildProcess
        #    #self.__cancelBuildersWin = CancelBuildersWin( 
        #    #        self.__wiz.getPreferences().getGUIFile( "cancelbuilderswindow")
        #    #        , self.__wiz, platfInBuildProcess)
        #    #self.__cancelBuildersWin.show()
        #else:
        #    self.__wiz.stopAllBuilders()
        self.__wiz.stopAllBuilders()
        self.__btnStop.set_sensitive( False)

    def generatePendrive( self):
        return

    def __onAbout( self, widget):
        info = self.__wiz.getAboutInfo()
        dlg = gtk.AboutDialog()
        dlg.set_name( info[ "name"])
        dlg.set_version( info[ "version"])
        dlg.set_copyright( info[ "copyright"])
        dlg.set_authors( [info[ "author"] + " - " + info[ "email"]])
        dlg.run()
        dlg.destroy()

    def __onNewPlatform( self, widget):
        dlg = DlgNewPlatform( self.__wiz)
        dlg.show()
        
    def __onDeletePlatform( self, widget):
        return

    def __deletePlatform( self, platfname, model, modelIt):
        msg = "Are you sure you want to delete platform [" + platfname + "] an all its contents?"
        dlg = gtk.MessageDialog( None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, msg)
        response = dlg.run()
        dlg.destroy()
        if response == gtk.RESPONSE_YES:
            if self.__wiz.getPlatformStatus( platfname) == "STATUS_BUILD_IN_PROGRESS":
                oops = gtk.MessageDialog( None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK
                        , "Stop the ongoing build for this platform before trying to delete it!!")
                oops.run()
                oops.destroy()
            else:
                self.__wiz.deletePlatform( platfname)
                model.remove( modelIt)

    def __onButtonPressEvent( self, treeview, event):
        if event.button == 1:
            pass
        elif event.button == 2:
            pass
        if event.button == 3:
            platfname = ""
            self.__popup = gtk.Menu()
            self.__popupDeleteItem = gtk.MenuItem( "Delete this platform")
            self.__popup.append( self.__popupDeleteItem)
            self.__popupDeleteItem.show()
            x = int(event.x)
            y = int(event.y)
            time = event.time
            pthinfo = treeview.get_path_at_pos(x, y)
            if pthinfo is not None:
                selection = treeview.get_selection()
                path, col, cellx, celly = pthinfo

                # This line is necessary cos the rigth-click doesn't 
                # set 'iter' for the first time after calling 'get_selected()'
                selection.select_path( path)
                model, modelIt = selection.get_selected()
                platfname = model[ path][ 0]
                treeview.grab_focus()
                treeview.set_cursor( path, col, 0)
                type( modelIt)
                self.__popupDeleteItem.connect_object( "activate", self.__deletePlatform, platfname, model, modelIt)
                self.__popup.popup( None, None, None, event.button, time)
            return 1

